//-----------------------------------------------------------
//Author : H4304 
//Projet : ciai 4IF
//Thread : impression
//Description : Rajoute une etiquette a un carton conditionne
//-----------------------------------------------------------

//----------Include 
#include "../Outils/config.h"
#include "../Outils/simulation.h"
#include "impression.h"
#include <stdio.h>
#include <string.h>
#include <mqueue.h>
#include <time.h>
//------------

//-----Constantes 
#define ZERO 0
//-----------

void *Impression()
{
	// Declaration variables 	
	unsigned int etat_impression; 
	
	//Messages 
	MSG_versArchivage msg_versArchivage; 
	MSG_carton msg_carton;
	MSG_versErreur msg_versErreur;
	MSG_retErreur msg_retErreur;  

	//Boites aux lettres 
	mqd_t conditionnement_impression;
	mqd_t impression_palette;
	mqd_t impression_archivage;
	mqd_t impression_erreur;
	mqd_t erreur_impression; 
	
	// Valeur retournee par les boites aux lettres en lecture 
	int bytes_read;
	
	// Priorite des messages envoyes  
	unsigned int priorite_message = PRIO_MSG_L;   
	
	//----------- Phase d initialisation

	// Ouverture des boites aux lettres 
	conditionnement_impression =  mq_open(BAL_versImpression,O_RDONLY); // En Lecture seulement 
	impression_palette =  mq_open(BAL_versPalette,O_WRONLY); // En Ecriture seulement 
	impression_archivage =  mq_open(BAL_versArchivage,O_WRONLY); // En Ecriture seulement
	impression_erreur =  mq_open(BAL_versErreur,O_WRONLY); // En Ecriture seulement 
	erreur_impression = mq_open(BAL_retErreur,O_RDONLY); //  En Lecture seulement 
	
	//----- Fin Phase d initialisation
	
	//------------ Phase moteur 
	for(;;)
	{
		// Attente d un message de conditionnement   
		bytes_read = mq_receive(conditionnement_impression,(char*) &msg_carton,sizeof(MSG_carton),NULL);
		if (bytes_read == -1)
  		{
   			perror("[ImpressionThread] Echec lors de la reception ");
  		}
  		else
		{
			if (msg_carton.type == FIN_PROD)
			{
				// Modification du message a envoyer a Palette  
				msg_carton.numCarton = ZERO; 
				msg_carton.typeProduit = ZERO;
			
				// Envoi de FIN APPLICATION a Palette 
				if (0 != mq_send (impression_palette,(char*)&msg_carton,sizeof(MSG_carton),PRIO_MSG_L))
				{
					perror("[ImpressionThread] Echec envoi FIN APPLI a Palette "); 
				}
					//Fermeture des boites aux lettres 
				mq_close(erreur_impression); 
				mq_close(impression_erreur);
				mq_close(impression_archivage);
				mq_close(impression_palette);
				mq_close(conditionnement_impression);
				pthread_exit(0); 
			}
			else
			{

				if (msg_carton.type == FIN_APPLI)
				{
					// Modification du message a envoyer a Palette  
					msg_carton.numCarton = ZERO; 
					msg_carton.typeProduit = ZERO;
			
					// Envoi de FIN APPLICATION a Palette 
					if (0 != mq_send (impression_palette,(char*)&msg_carton,sizeof(MSG_carton),PRIO_MSG_L))
					{
						perror("[ImpressionThread] Echec envoi FIN APPLI a Palette "); 
					}
						//Fermeture des boites aux lettres 
					mq_close(erreur_impression); 
					mq_close(impression_erreur);
					mq_close(impression_archivage);
					mq_close(impression_palette);
					mq_close(conditionnement_impression);	
					pthread_exit(0); 
				}
				else
				{
					// Verification de l etat de l imprimante 
					etat_impression = EtatImpression();					  
					if (etat_impression == IMPRESSION_NOK)
					{
						// Creation du message a envoyer a Erreur 
						msg_versErreur.source = T_IMPRESSION; 
						msg_versErreur.message = IMP_HS; 
						msg_versErreur.heure = time(NULL);
						msg_versErreur.numLot = msg_carton.numLot; 
						msg_versErreur.cartonEnCours = msg_carton.numCarton;
				
						// Envoi de IMPRIMANTE HS a Erreur 
						if (0 != mq_send (impression_erreur, (char*)&msg_versErreur,sizeof(MSG_versErreur),PRIO_MSG_L))
						{
							perror("[ImpressionThread] Echec envoi IMP_HS a Erreur "); 
						} 
						
						// Attente du compte rendu Erreur 
						bytes_read = mq_receive(erreur_impression,(char*)&msg_retErreur,sizeof(MSG_retErreur),NULL);
						if (bytes_read == -1)
	  					{
	   						perror("[ImpressionThread] Echec lors de la reception ");
	  					}
						else
						{
							if (msg_retErreur.reponse == FIN_APPLI)
							{
								// Modification du message a envoyer a Palette   
								msg_carton.type = FIN_APPLI;
								msg_carton.numCarton = ZERO; 
								msg_carton.typeProduit = ZERO;
								// Envoi de FIN APPLICATION a Palette 
								if (0 != mq_send (impression_palette,(char*)&msg_carton,sizeof(MSG_carton),PRIO_MSG_L))
								{
									perror("[ImpressionThread] Echec envoi FIN APPLI a Palette "); 
								}
								// Retrait du deuxieme message a ne pas traiter 
								bytes_read = mq_receive(conditionnement_impression,(char*)&msg_carton,sizeof(MSG_carton),NULL);
								// Retrait du deuxieme message a ne pas traiter 
								bytes_read = mq_receive(conditionnement_impression,(char*)&msg_carton,sizeof(MSG_carton),NULL);
								//Fermeture des boites aux lettres 
								mq_close(erreur_impression); 
								mq_close(impression_erreur);
								mq_close(impression_archivage);
								mq_close(impression_palette);
								mq_close(conditionnement_impression);
								pthread_exit(0); 
							}
							else
							{
								// Sinon REPRISE : Envoi du carton a palette 
								mq_send (impression_palette,(char*)&msg_carton,sizeof(MSG_carton),PRIO_MSG_L);
								printf("[ImpressionThread] CARTON IMPRIME \n ");
								// Creation du compte rendu  
								msg_versArchivage.source = T_IMPRESSION; 
								msg_versArchivage.message = IMP_OK;
								msg_versArchivage.heure = time(NULL); 
								msg_versArchivage.cartonEnCours = msg_carton.numCarton;
								msg_versArchivage.numLot = msg_carton.numLot;
								msg_versArchivage.type = ARCHIVAGE; 

								// Envoi du compte rendu a Archivage 
								if (0 != mq_send (impression_archivage,(char*)&msg_versArchivage,sizeof(MSG_versArchivage),PRIO_MSG_L))
								{
									perror("[ImpressionThread] Echec envoi Compte Rendu a ARCHIVAGE ");
								}
							} 
						}
					}
					else
					{
						// Envoi du carton a palette 
						if (0 != mq_send (impression_palette,(char*)&msg_carton,sizeof(MSG_carton),PRIO_MSG_L))
						{
							perror("[ImpressionThread] Echec envoi Carton a Palette ");
						}
						printf("[ImpressionThread] CARTON IMPRIME \n "); 
						// Creation du compte rendu  
						msg_versArchivage.source = T_IMPRESSION; 
						msg_versArchivage.message = IMP_OK;
						msg_versArchivage.heure = time(NULL); 
						msg_versArchivage.cartonEnCours = msg_carton.numCarton;
						msg_versArchivage.numLot = msg_carton.numLot;
						msg_versArchivage.type = ARCHIVAGE; 

						// Envoi du compte rendu a Archivage 
						if (0 != mq_send (impression_archivage,(char*)&msg_versArchivage,sizeof(MSG_versArchivage), priorite_message))
						{
							perror("[ImpressionThread] Echec envoi Compte Rendu a ARCHIVAGE ");
						}					
					} 
				}
			}
						 
		} 
		// Retrait du deuxieme message a ne pas traiter 
		bytes_read = mq_receive(conditionnement_impression,(char*)&msg_carton,sizeof(MSG_carton),NULL); 
	}
	//------ Fin Phase moteur 
	
	//-------Phase de destruction 
	//Fermeture des boites aux lettres 
	mq_close(erreur_impression); 
	mq_close(impression_erreur);
	mq_close(impression_archivage);
	mq_close(impression_palette);
	mq_close(conditionnement_impression);
	//----Fin Phase de destruction 	
}
